/*   Copyright © 2009 Mark Gil Torres
 *
 *   This file is part of mtoolkit.
 *
 *   mtoolkit is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   any later version.
 *
 *   mtoolkit is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with mtoolkit.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "../include/integer.h"
#define BOOST_TEST_MODULE Integer test
#include <boost/test/included/unit_test.hpp>

using namespace mt;


BOOST_AUTO_TEST_CASE(constructor_test) {
  Integer x1;
  BOOST_CHECK_EQUAL(x1,0);

  Integer x2(1);
  BOOST_CHECK_EQUAL(x2,1);

  Integer x3("123456789000");
  Integer x4("123456789000");
  BOOST_CHECK_EQUAL(x3,x4);

  std::string s("12345");
  Integer x5(s);
  BOOST_CHECK_EQUAL(x5,12345);

  Integer x6(123);
  Integer x7(x6);
  BOOST_CHECK_EQUAL(x7,123);
  BOOST_CHECK_EQUAL(x6,x7);

  Integer x8 = 1;
  BOOST_CHECK_EQUAL(x8,1);

  Integer x9 = std::string("2");
  BOOST_CHECK_EQUAL(x9,2);

  Integer x10 = 3;
  Integer x11 = x10;
  BOOST_CHECK_EQUAL(x10,x11);

  Integer x12("2");
  BOOST_CHECK_EQUAL(x12,2);

}

BOOST_AUTO_TEST_CASE(arithmetic_test) {
  Integer x1(-1);
  Integer x2(1);
  Integer x3(0);
  Integer x4("123456789000");
  Integer x5("-123456789000");
  Integer x6(31);

  BOOST_CHECK_EQUAL(x1+x2,0);
  BOOST_CHECK_EQUAL(x1-x2,-2);
  BOOST_CHECK_EQUAL(x2-x1,2);
  BOOST_CHECK_EQUAL(x1*x2,-1);
  BOOST_CHECK_EQUAL(x1/x2,-1);
  BOOST_CHECK_EQUAL(x1%x2,0);

  Integer x7("246913578000");
  Integer x8("15241578750190521000000");
  Integer x9("3982477064");
  Integer x10(16);
  BOOST_CHECK_EQUAL(x4+x4,x7);
  BOOST_CHECK_EQUAL(x4*x4,x8);
  BOOST_CHECK_EQUAL(x4/x6,x9);
  BOOST_CHECK_EQUAL(x4%x6,x10);
  BOOST_CHECK_EQUAL(x6/x4,0);
  BOOST_CHECK_EQUAL(x6%x4,31);

  BOOST_CHECK_EQUAL(x6+69,100);
  BOOST_CHECK_EQUAL(x6-69,-38);
  BOOST_CHECK_EQUAL(x6*3,93);
  BOOST_CHECK_EQUAL(x6/3,10);
  BOOST_CHECK_EQUAL(x6%3,1);

  BOOST_CHECK_EQUAL(0+x6,31);
  BOOST_CHECK_EQUAL(100-x6,69);
  BOOST_CHECK_EQUAL(2*x6,62);
  BOOST_CHECK_EQUAL(5/x6,0);
  BOOST_CHECK_EQUAL(5%x6,5);
}

BOOST_AUTO_TEST_CASE(relational_test) {
  Integer x1(0);
  Integer x2(1);
  Integer x3(-1);
  BOOST_CHECK_EQUAL(x1==x1,true);
  BOOST_CHECK_EQUAL(x1<=x1,true);
  BOOST_CHECK_EQUAL(x1>=x1,true);
  BOOST_CHECK_EQUAL(x1<x2,true);
  BOOST_CHECK_EQUAL(x1<=x2,true);
  BOOST_CHECK_EQUAL(x2>x3,true);
  BOOST_CHECK_EQUAL(x2>=x3,true);

  BOOST_CHECK_EQUAL(x1==0,true);
  BOOST_CHECK_EQUAL(x1<=10,true);
  BOOST_CHECK_EQUAL(x1>=-10,true);
  BOOST_CHECK_EQUAL(x1<20,true);
  BOOST_CHECK_EQUAL(x1<=21,true);
  BOOST_CHECK_EQUAL(x2>-20,true);
  BOOST_CHECK_EQUAL(x2>=-21,true);

  BOOST_CHECK_EQUAL(0==x1,true);
  BOOST_CHECK_EQUAL(-10<=x1,true);
  BOOST_CHECK_EQUAL(10>=x1,true);
  BOOST_CHECK_EQUAL(-20<x2,true);
  BOOST_CHECK_EQUAL(-21<=x2,true);
  BOOST_CHECK_EQUAL(20>x3,true);
  BOOST_CHECK_EQUAL(21>=x3,true);
}

BOOST_AUTO_TEST_CASE(functions_test) {
  Integer x1(3);
  Integer x2(7);
  Integer x3(42);
  Integer x4(18);

  BOOST_CHECK_EQUAL(gcd(x1,x2),1);
  BOOST_CHECK_EQUAL(gcd(x1,x3),3);
  BOOST_CHECK_EQUAL(gcd(x4,x3),6);

  BOOST_CHECK_EQUAL(lcm(x1,x2),21);
  BOOST_CHECK_EQUAL(lcm(x1,x4),18);
  BOOST_CHECK_EQUAL(lcm(x2,x4),7*18);

  Integer x5(-1);
  Integer x6("-123456789000");
  Integer x7("123456789000");
  BOOST_CHECK_EQUAL(abs(x5),1);
  BOOST_CHECK_EQUAL(abs(x6),x7);
}
